package jrain.fw.script.operator;

import jrain.fw.script.tools.ELException;
import jrain.fw.script.tools.Logger;

//取余操作
public class ModulusOperator extends BinaryOperator {

	public static final ModulusOperator SINGLETON = new ModulusOperator();

	public ModulusOperator() {
	}

	public String getOperatorSymbol() {
		return "%";
	}

	public Object apply(Object pLeft, Object pRight, Object pContext, Logger pLogger) throws ELException {
		if (pLeft == null && pRight == null) {
			if (pLogger.isLoggingWarning()) {
				pLogger.logWarning(Constants.ARITH_OP_NULL, getOperatorSymbol());
			}
			return PrimitiveObjects.getInteger(0);
		}

		if ((pLeft != null && (Coercions.isFloatingPointType(pLeft) || Coercions.isFloatingPointString(pLeft)))
				|| (pRight != null && (Coercions.isFloatingPointType(pRight) || Coercions.isFloatingPointString(pRight)))) {
			double left = Coercions.coerceToPrimitiveNumber(pLeft, Double.class, pLogger).doubleValue();
			double right = Coercions.coerceToPrimitiveNumber(pRight, Double.class, pLogger).doubleValue();

			try {
				return PrimitiveObjects.getDouble(left % right);
			} catch (Exception exc) {
				if (pLogger.isLoggingError()) {
					pLogger.logError(Constants.ARITH_ERROR, getOperatorSymbol(), "" + left, "" + right);
				}
				return PrimitiveObjects.getInteger(0);
			}
		} else {
			long left = Coercions.coerceToPrimitiveNumber(pLeft, Long.class, pLogger).longValue();
			long right = Coercions.coerceToPrimitiveNumber(pRight, Long.class, pLogger).longValue();

			try {
				return PrimitiveObjects.getLong(left % right);
			} catch (Exception exc) {
				if (pLogger.isLoggingError()) {
					pLogger.logError(Constants.ARITH_ERROR, getOperatorSymbol(), "" + left, "" + right);
				}
				return PrimitiveObjects.getInteger(0);
			}
		}
	}

}
